/*
 * @(#)ProxyWatcher.java
 *
 * 03L7246 (c) Copyright IBM Corp. 1996, 1998
 *
 * The program is provided "as is" without any warranty express or
 * implied, including the warranty of non-infringement and the implied
 * warranties of merchantibility and fitness for a particular purpose.
 * IBM will not be liable for any damages suffered by you as a result
 * of using the Program. In no event will IBM be liable for any
 * special, indirect or consequential damages or lost profits even if
 * IBM has been advised of the possibility of their occurrence. IBM
 * will not be liable for any third party claims against you.
 */

package example.watcher;

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.net.URL;

import com.ibm.aglet.Aglet;
import com.ibm.aglet.AgletContext;
import com.ibm.aglet.AgletException;
import com.ibm.aglet.AgletProxy;
import com.ibm.aglet.InvalidAgletException;
import com.ibm.aglet.Message;
import com.ibm.aglet.util.AddressChooser;

/**
 * <tt> ProxyWatcher </tt> is an aglet which dispatches a slave aglet and
 * monitors proxies of the remote context. This is an example of
 * these features in Aglets.
 *
 * <ol>
 * <li> remote messaging
 * <li> delegation event model
 * <li> concurrency control by <tt> waitMessage()/notifyMessage() </tt>
 * <li> persistency
 * <li> activation by message
 * <li> remote control of an aglet.
 * </ol>
 * Please use JDK1.1 or later to compile these classes.
 * 
 * @version     1.00    $Date: 1999/10/27 05:16:39 $
 * @author      Mitsuru Oshima
 * @see examples.watcher.WatcherSlave
 * @updated by Shintaro Kosugi $Date: 98/11/24
 */
public class ProxyWatcher extends Aglet {
    transient AgletContext ac;
    WatcherFrame frame;
    AgletProxy slave = null;

    public void onCreation(Object o) {
		ac = getAgletContext();
		frame = new WatcherFrame(this);
		frame.pack();
		frame.setVisible(true);
    }

    public boolean handleMessage(Message msg) {
	if (msg.sameKind("update")) {
	    String s = String.valueOf(msg.getArg());
	    frame.update(s);
	} else return false;
	return true;
    }

    public void go(String address) {
	try {
	    //
	    // Creates another aglet
	    //
	    if (slave ==  null) {
		slave = ac.createAglet(getCodeBase(),
				       "keio.ics.nak.watcher.WatcherSlave",
				       getAgletID());
	    }
	    //
	    // Obtain the remote proxy.
	    //
	    Message gonext = new Message("gonext", new URL(address));
	    // update the proxy
	    slave = (AgletProxy)slave.sendMessage(gonext);

	} catch (Exception ex) {
	    if (slave != null) {
		try {
		    slave.dispose();
		} catch (Exception exx) {
		    exx.printStackTrace();
		}
	    }
	    ex.printStackTrace();
	}
    }

    public void sendMessage(Message msg) {
	if (slave != null) {
	    try {
		//
		// Remote messaging.
		//
		slave.sendAsyncMessage(msg);
	    } catch (InvalidAgletException ex) {
		ex.printStackTrace();
	    }
	}
    }

    public void move(String address) {
	try {
	    URL dest = new URL(address);
	    slave = slave.dispatch(dest);
	} catch (AgletException ex) {
	    ex.printStackTrace();
	} catch (java.io.IOException ex) {
	    ex.printStackTrace();
	}
    }

    public void terminate() {
	if (slave == null) {
	    return;
	}
	try {
	    //
	    // you can call the dispose method on the remote aglet.
	    //
	    slave.dispose();
	} catch (InvalidAgletException ex) {
	    ex.printStackTrace();
	}
    }
}

class WatcherFrame extends Frame implements WindowListener,ActionListener{
    ProxyWatcher aglet;
    TextArea text = new TextArea(10,10);
    AddressChooser address = new AddressChooser(15);
    Button go = new Button("Go!");
	Button start = new Button("Start");
	Button stop = new Button("Stop");
	Button sleep = new Button("Sleep");
	Button move = new Button("Move");
	Button terminate = new Button("Terminate");
    
    WatcherFrame(ProxyWatcher a) {
		aglet = a;
		setLayout(new BorderLayout());
		add("North", address);
		add("Center", text);
		Panel p = new Panel();
		p.setLayout(new FlowLayout());

		addWindowListener(this);
		go.addActionListener(this);
		start.addActionListener(this);
		stop.addActionListener(this);
		sleep.addActionListener(this);
		move.addActionListener(this);
		terminate.addActionListener(this);

		p.add(go);
		p.add(start);
		p.add(stop);
		p.add(sleep);
		p.add(move);
		p.add(terminate);
		add("South", p);
	}
    
	void update(String s) {
		text.setText(s);
    }
	
	/**
     * Handles the action event
     * @param ae the event to be handled
     */
	public void actionPerformed(ActionEvent ae){
		if("Go!".equals(ae.getActionCommand())){
			aglet.go(address.getAddress());
	    }else if("Start".equals(ae.getActionCommand())){
			aglet.sendMessage(new Message("start"));
		}else if("Stop".equals(ae.getActionCommand())){
			aglet.sendMessage(new Message("stop"));
		}else if("Sleep".equals(ae.getActionCommand())){
			aglet.sendMessage(new Message("sleep"));
		}else if("Move".equals(ae.getActionCommand())){
			aglet.move(address.getAddress());
		}else if("Terminate".equals(ae.getActionCommand())){
			aglet.terminate();
		}
	}
	
	/**
     * Handles the window event
     * @param we the event to be handled
     */
	
	public void windowClosing(WindowEvent we){
		dispose();
	}
	
	public void windowOpened(WindowEvent we){}
	
	public void windowIconified(WindowEvent we){}
	
	public void windowDeiconified(WindowEvent we){}
	
	public void windowClosed(WindowEvent we){}
	
	public void windowActivated(WindowEvent we){}
	
	public void windowDeactivated(WindowEvent we){}

    
}
